

const eps:number = 1e-8;
class Point
{
    public x:any = 0;
    public y:any = 0;
    constructor(x,y) {
        this.x = x;
        this.y =y;
    }

    public static sub( a:Point, b:Point):Point
    {
        return new Point(a.x-b.x, a.y-b.y);
    }
    public static dot( a:Point, b:Point):number
    {
        return a.x*b.x + a.y*b.y;
    }

   public static cross( a:Point, b:Point):number
    {
         return a.x*b.y - a.y*b.x;
    }
    	//向量的规格化：就是让向量的长度等于1;
	//向量长度 length = sqrt(x² + y² + z²);
	//要让长度=1，那么向量 V(normalize) = V(src)/length=V(src)/sqrt(x² + y² + z²)=V(x/length,y/length,z/length);
	public normalize()
	{
		//float sqr = v.x*v.x + v.y*v.y + v.z*v.z;
		//return v*inversesqrt(sqr);
 
		let len:number = Math.sqrt(this.x*this.x + this.y*this.y ); //向量长度;
		this.x = this.x/len;
        this.y= this.y/len;
	}

    public rotate(angle:number)
    {
        this.x =  this.x*Math.cos(angle)-this.y*Math.sin(angle); 
        this.y =  this.x*Math.sin(angle)-this.y*Math.cos(angle); 
    }

    public normal()
    {
        let newx =  -this.y; 
        let newy =  this.x; 
        return new Point(newx,newy);
    }
};


class Line
{
    public start:Point;
    public end:Point;

    constructor(start:Point,end:Point)
    {
        this.start = start;
        this.end = end;
    }

    public getdir():Point
    {
        let dir = Point.sub(this.end,this.start);
        dir.normalize();
        return dir;
    }

    public isPointLeftOfLine(pt:Point)
    {
        let tmpx = (this.start.x - this.end.x) / (this.start.y - this.end.y) * (pt.y - this.end.y) + this.end.x;

        if (tmpx > pt.x)//当tmpx>p.x的时候，说明点在线的左边，小于在右边，等于则在线上。
        {
            return true;
        }
        
        return false;
    }

    //获取向量之间的夹角 弧度单位
    public static getAngleBetweenLine(line1:Line,line2:Line):number
    {
        let vector1 = Point.sub(line1.end,line1.start);
        let vector2 = Point.sub(line2.end,line2.start);
        let angle:number = Math.atan2(vector2.y, vector2.x) - Math.atan2(vector1.y, vector1.x);
        if (angle < 0) angle += 2 * Math.PI;
        return angle;
    }

    //判断以线段1和线段2为对角线的矩形是否重叠
    public static checkDiagonalRectOverlap(line1:Line,line2:Line):boolean
    {
        if(Math.min(line1.start.x,line1.end.x)<=Math.max(line2.start.x,line2.end.x)&& 
        Math.min(line2.start.x,line2.end.x)<=Math.max(line1.start.x,line1.end.x)&&
        Math.min(line2.start.y,line2.end.y)<=Math.max(line1.start.y,line1.end.y)&&
        Math.min(line1.start.y,line1.end.y)<=Math.max(line2.start.y,line2.end.y))
        {
            return true;
        }
　　    return false;
    }
    //判断线段l1和线段l2是否相交
    public static  Seg_inter_line(line1:Line,line2:Line):boolean 
    {
        //以线段1和线段2为对角线的矩形不重叠，则不相交
        if(!this.checkDiagonalRectOverlap(line1,line2))
        {
            return false;
        }
        //ca * ba
        let u= Point.cross( Point.sub(line2.start, line1.start), Point.sub(line1.end, line1.start));
        //da * ba
        let v= Point.cross( Point.sub(line2.end, line1.start), Point.sub(line1.end, line1.start));
        //ac * cd
        let w= Point.cross( Point.sub(line1.start, line2.start), Point.sub(line2.end, line2.start));
        //bc * cd
        let z= Point.cross( Point.sub(line1.end, line2.start), Point.sub(line2.end, line2.start));

        return u*v <eps &&  w*z<eps;
    }

};